package com.tangding.hprose.api.server.command.impl.role;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.tangding.common.exception.GException;
import com.tangding.hprose.api.server.command.Command;
import com.tangding.hprose.api.server.command.Response;
import com.tangding.service.dao.role.PermissionRepository;
import com.tangding.service.dao.role.RoleRepository;
import com.tangding.service.dao.user.UserRepository;
import com.tangding.service.entity.role.Permission;
import com.tangding.service.entity.role.Role;
import com.tangding.service.entity.role.RoleVO;
import com.tangding.service.entity.user.User;

/**
 * @description 
 *
 * @author Ranger
 * @version 2017年12月1日_下午4:45:16
 *
 */
@Component
public class GetRoles implements Command{

	static UserRepository userRepository;
	static RoleRepository roleRepository;
	static PermissionRepository permissionRepository;
	
	@Autowired
	public void setUserRepository(UserRepository userRepository) {
		GetRoles.userRepository = userRepository;
	}
	@Autowired
	public void setRoleRepository(RoleRepository roleRepository) {
		GetRoles.roleRepository = roleRepository;
	}
	@Autowired
	public void setPermissionRepository(PermissionRepository permissionRepository) {
		GetRoles.permissionRepository = permissionRepository;
	}
	
	@Override
	public Response exe(Object... params) throws GException {
		String uid = (String) params[0];
		User user = userRepository.getUserByUid(uid);
		Set<Integer> roleIds = user.getRoles();
		Set<Role> roles = new HashSet<>();
		Set<RoleVO> vos = new HashSet<>();
		Set<Permission> permissions = new HashSet<>();
		if (roleIds != null) {
			roleIds.forEach(roleId -> {
				Role role = roleRepository.getRole(roleId);
				if (role != null) {
					roles.add(role);
				}
			});
			
			roles.forEach(role -> {
				RoleVO vo = role2VO(role);
				getMyDownlineRoleVOs(role, vo, permissions);
				vos.add(vo);
			});
		}
		
		List<User> users = new ArrayList<>();
		users.add(user);
		
		List<Map<String, Object>> userVos = new ArrayList<>();
		
		//把自己加入vo列表
		Map<String, Object> vo = buildUserVO(user);
		userVos.add(vo);
		findChildUser(uid, users, userVos);
		
		Map<String, Object> result = new HashMap<>();
		result.put("permissions", permissions);
		result.put("roles", vos);
		result.put("users", userVos);
		
		return doResponseSucc(result);
	}
	//递归找自账号
	public static void findChildUser(String pid, List<User> users, List<Map<String, Object>> vos) {
		Map<String, User> userMap = userRepository.getUserMap();
		userMap.values().forEach(user -> {
			if (pid != null && pid.equals(user.getPuid())) {//当前层帐号的自账号
				users.add(user);
				
				Map<String, Object> vo = buildUserVO(user);
				vos.add(vo);
				findChildUser(user.getUid(), users, vos);
			}
		});
	}
	
	public static Map<String, Object> buildUserVO(User user) {
		Map<String, Object> vo = new HashMap<>();
		vo.put("uid", user.getUid());
		vo.put("name", user.getName());
		
		return vo;
	}
	
	public static void getMyDownlineRoleVOs(Role role, RoleVO pvo, Set<Permission> permissions) {
		if (role != null) {
			List<Integer> permissionIds = role.getPermission();
			if (permissionIds != null) {
				permissionIds.forEach(permissionId -> {
					if (permissionRepository.getPermissions().containsKey(permissionId)) {
						permissions.add(permissionRepository.getPermissions().get(permissionId));
					}
				});
			}
			
			Set<Role> childrenSet = roleRepository.getOneDownLevelChildren(role.getRoleId());
			if (childrenSet.size() > 0) {
				List<RoleVO> children = pvo.getChildren();
				if (children == null) {
					children = new ArrayList<>();
					pvo.setChildren(children);
				}
				
				for (Role r : childrenSet) {
					pvo = role2VO(r);
					children.add(pvo);
					getMyDownlineRoleVOs(r, pvo, permissions);
				}
			}
		}
	}
	
	public static RoleVO role2VO(Role role) {
		RoleVO vo = new RoleVO();
		int roleId = role.getRoleId();
		Map<String, User> userMap = userRepository.getUserMap();
		userMap.forEach((name, u) -> {
			Set<Integer> roles = u.getRoles();
			if (roles != null && roles.size() > 0) {
				if (roles.contains(roleId)) {
					vo.setData(u.getName());
					return;
				}
			}
		});
		vo.setTitle(role.getRoleName());
		vo.setId(roleId);
		return vo;
	}

}
